#include "proc/self.h"
// #include "process.h"

// ![0]
bool self_status_of_buffer(char *buf, SelfStatusInfo *info) {
    if (isNull(buf)) return false;

    for (int i = 0; i < sizeof(proc_self_status_properties)/sizeof(proc_self_status_properties[0]); i++) {
        if (LineStartWith(buf, (char*)proc_self_status_properties[i])) {
            // printf("--> %s\n", buf); 
            GSList *block, *splitT;
            char *part;
            char *value;
            block = split_cnt(buf, ':', 1);
            // if (!LineEqual((char*)g_slist_nth(block, 0)->data, (char*)proc_self_status_properties[i])) {
            //     GS_FREE_ALL_CLEAN(block)
            //     return false;
            // }
            char comm[256] = {0};
            part = LineTrim((char*)g_slist_nth(block, 1)->data);
            if (i<=6) {
                switch (i) {
                    case 0: strcpy(info->Name, part); break;
                    case 1: strcpy(info->Umask, part); break;
                    case 2: strcpy(info->State, part); break;
                    case 3: //strcpy(info->Tgid, part); 
                        get_comm_by_pid(part, comm, sizeof(comm));
                        LineTrim_buf(comm, comm);
                        sprintf(info->Tgid, "%s(%s)", part,comm);
                    break;
                    case 4: // strcpy(info->Ngid, part); 
                        get_comm_by_pid(LineEqual(part, "0")?"1":part, comm, sizeof(comm));
                        LineTrim_buf(comm, comm);
                        sprintf(info->Ngid, "%s(%s)", part,comm);
                    break;
                    case 5: // strcpy(info->Pid, part); 
                        get_comm_by_pid(part, comm, sizeof(comm));
                        LineTrim_buf(comm, comm);
                        sprintf(info->Pid, "%s(%s)", part,comm);
                    break;
                    case 6: // strcpy(info->PPid, part); 
                        get_comm_by_pid(part, comm, sizeof(comm));
                        LineTrim_buf(comm, comm);
                        sprintf(info->PPid, "%s(%s)", part,comm);
                    ;break;
                }
            } else {
                splitT = split(part, ' ');
                value = g_slist_nth(splitT, 0)->data;
                switch (i) {
                    case 7: info->VmPeak = atol(value); break;
                    case 8: info->VmSize = atol(value); break;
                    case 9: info->VmLck = atol(value); break;
                    case 10: info->VmPin = atol(value);break;
                    case 11: info->VmHWM = atol(value); break;
                    case 12: info->VmRSS = atol(value); break;
                }

                GS_FREE_ALL_CLEAN(splitT)
            }
            free(part);

            GS_FREE_ALL_CLEAN(block)
        }
    }
    return true;
}
// ![0]

bool proc_self_status_of_buffer(char *buf, SelfStatusInfo *info) {
    if (isNull(buf)) return false;

    GSList *splitT = split(buf, '\n');
    // g_slist_foreach(splitT, (GFunc)printf_iterator, "->");
    for (GSList *iter = splitT; iter; iter = iter->next) {
        self_status_of_buffer(iter->data, info);
    }
    GS_FREE_ALL_CLEAN(splitT)

    return true;
}

bool initSelfStatusInfo(SelfStatusInfo *info) {
    if(!FileExists(LINUX_OS_PROC_SELF_STATUS)) return false;

    char buffer[10000] = {0};
    if (FileReadToBuffer(LINUX_OS_PROC_SELF_STATUS, buffer, sizeof(buffer)) > 0) {
        return proc_self_status_of_buffer(buffer, info);
    }
    return false;
}